/*******************
* add_seq_vars-2.sas
*
* Add various flags and sequence variables to the
* cohort data to facilitate analysis.
*
******************/

%macro makeseqvars(indata, outdata, firstdate);
  * indata: all patient records with the index procedure.
  * outdata: output dataset - with transfers;
  * firstdate: earliest date for the cohort (so excluding lookback period);
  
******************************************************************************
* ny and on have episodes defined as all transfers between acute facilities, while
* nsw has separations for each facility. first want to create episode where these transfers overlap 
 
* flag sequential separations before a procedure (within 10 days)
proc sort data=&indata out = indata_temp;
  by ppn descending episode_start_date descending episode_start_time episode_end_date episode_end_time;
run;

data indata_temp; 
	set indata_temp;
	by ppn; 
	retain before_index;
	next_start_date = lag(episode_start_date); 
	format next_start_date date9.; 
	time_to_next_episode = next_start_date - episode_end_date; 
	if first.ppn then do ; 
		time_to_next_episode = .; 
		if index_flag = 1 then before_index = 1; 
		else before_index = 0; 
	end;
	else do; 
		if index_flag = 1 then before_index = 1; 
		else if time_to_next_episode >= 10 then before_index = 0; 
	end;  
run; 

* flag sequential separations after a procedure (within 90 days)
proc sort data= indata_temp;
  by ppn episode_start_date episode_start_time episode_end_date episode_end_time;
run;

data indata_temp; 
	set indata_temp; 
	by ppn; 
	retain after_index;
	previous_end_date = lag(episode_end_date); 
	format previous_end_date date9.;  
	time_from_last_episode = episode_start_date - previous_end_date; 
	if first.ppn then do ; 
		time_from_last_episode = .; 
		if index_flag = 1 then after_index = 1; 
		else after_index = 0; 
	end;
	else do; 
		if index_flag = 1 then after_index = 1; 
		else if time_from_last_episode > 100 then after_index = 0; 
	end; 
run; 

data indata_temp; 
	set indata_temp; 
	where index_flag = 1 or after_index = 1 or before_index = 1; 
run; 

******************************************************************************;
* need new version of facility identifiers;
proc sql;
	create table tempx as
	select a.*, b.facility_identifier_recode2, b.facility_trans_to_recode2, b.facility_trans_from_recode2
	from indata_temp as a
	left join apdc.apdc_masked_identifiers_v2 as b
	on a.recnum = b.recnum;
quit;

* first sort by ppn, admission, separation;
proc sort data=tempx;
  by ppn episode_start_date episode_start_time episode_end_date  episode_end_time;
run;

data temp1;
  	set tempx;
  	retain fileseq ppnseq episode_of_care trnsseq;
  	by ppn;
* fileseq lets us always get back to same file order;
  	if _n_ = 1 then fileseq = 1;
  	else fileseq+1;
* ppnseq numbers all records for each patient;
 	if first.ppn then ppnseq = 1;
 	else ppnseq+1;
 * episode_of_care numbers each sequence of transfers (full hospital stay);
 * trnsseq numbers hospital episodes within each episode_of_care;
 	if first.ppn then episode_of_care = 0;
 	lagfacility = lag(facility_identifier_recode2);
 	lagtransferto = lag(facility_trans_to_recode2);
	IF ppnseq = 1 THEN DO;
		lagfacility=.; lagtransferto=.;
	END;
	RETAIN stay_end stay_sepmode;
	IF ppnseq = 1 then do;
		trnsseq = 1;
    	stay_end = episode_end_date;
    	stay_sepmode = mode_of_separation_recode;
	end;
	* if starts before stay_end and continues beyond, update stay_end;
	else if (episode_start_date <= stay_end and stay_end < episode_end_date) then do; *and episode_of_care_type ne '2' then do; * << could be this add here;
		stay_end=episode_end_date;
    	stay_sepmode = mode_of_separation_recode;
	end;
	if ppnseq > 1 then do;
	/* Restart episode count if the next separation is not acute type (need to exclude rehab care from episode, like NY and ON) */ 
		if episode_of_care_type not in ('1','') then do; 
			trnsseq=1;
		end;
		else if episode_start_date < stay_end then do; /* starts before stay ends */
			trnsseq+1;
    	end;
		else if ((episode_start_date = stay_end or episode_start_date = stay_end+1) and /* start sameday or next day (to allow tranfers around midnight) */
			(stay_sepmode in ('5', '9') /* transfer recorded */
	   		or facility_identifier_recode2 = lagtransferto /* current hospital matches where patient was recorded being transferred to */
	   		or lagfacility = facility_trans_from_recode2)) /* previous hospital matches where patient recorded as being transferred from */
	   		then do;
				trnsseq+1;
				if episode_end_date > stay_end then do; /* update stay end and sepmode if current episode extends stay */
		   			stay_end = episode_end_date;
		   			stay_sepmode = mode_of_separation_recode;
		 		end;
	   		end;
     	ELSE trnsseq=1;
   		end;
   	if trnsseq = 1 then do;
     	episode_of_care+1;
     	stay_end = episode_end_date;
     	stay_sepmode = mode_of_separation_recode;
   	end;
run;

* start and end dates for each full hospital stay (episode_of_care);
proc sql;
  create table dates as
  select ppn, episode_of_care,
    min(episode_start_date) as start_eoc,
    max(episode_end_date) as end_eoc
	from temp1
    group by ppn, episode_of_care;
  
  create table temp2 as
  select a.*, b.start_eoc, b.end_eoc
  from temp1 as a
  inner join dates as b
  on a.ppn = b.ppn and a.episode_of_care = b.episode_of_care;
quit;
  
